package com.adcc.swingui.base;

import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;

import org.apache.log4j.Logger;

import com.adcc.cs.mina.client.MinaClient;
import com.adcc.cs.util.CommonUtil;
import com.adcc.swingui.bean.MenuRightComponentBean;
import com.adcc.swingui.util.I18n;
import com.jidesoft.action.CommandBarFactory;
/**
 * 菜单按钮超类
 * 外部可以通过菜单父Map查找到对应的父节点，然后再根据名称查找到子节点。
 * 如果要对子节点进行操作，节点必须存在，如果不存在记入warn日志。不影响业务。
 * @author charlie
 *
 */
public abstract class DefaultMenuBar extends CommandBarFactory {
	private static Logger logger = Logger.getLogger(DefaultMenuBar.class);

	/**
	 * 所有菜单响应事件
	 */
	protected static Map<String, DefaultMenuBar> menuBarMap = new HashMap<String, DefaultMenuBar>();
	/**
	 * 只存入叶子菜单
	 */
	protected static Map<String, AbstractButton> menuChildMap = new HashMap<String, AbstractButton>();
	/**
	 * 非叶子菜单
	 */
	protected static Map<String, AbstractButton> menuMap = new HashMap<String, AbstractButton>();
	/**
	 * 菜单源
	 */
	protected JComponent sourceComp ;
	/**
	 * swing框架容器
	 */
	protected Container container;
	/**
	 * 名称
	 */
	protected String name = this.getClass().getName();
	
	/**
	 * 构建菜单的配置名称
	 */
	protected String menuBuildName = "";
	
	public DefaultMenuBar(Container container) {
		this.container = container;
	}
	
	/**
	 * 需要被重写工具构造器
	 * @return
	 */
	protected abstract JComponent build();
	
	/**
	 * 离线状态判断,传递jcomp的isVisible值来控制menuItem的离线可用状态
	 * @return
	 */
	protected abstract void offLineVisiable(List<JComponent> jcomps);
	
	/**
	 * 国际化
	 */
	public void i18n(String className,List<JComponent> jcomps){
		if (jcomps != null) {
			for (Component comp : jcomps) {
				JComponent jcomp = (JComponent) comp;
				if (jcomp instanceof JMenu) {
					JMenu m = (JMenu) jcomp;
					m.setText(getI18nStr(className,m.getText()));
				} else if (jcomp instanceof JMenuItem) {
					JMenuItem mi = (JMenuItem) jcomp;
					mi.setText(getI18nStr(className,mi.getText()));
				}
			}
		}
	}
	
	private String getI18nStr(String className,String str) {
		return I18n.getLabel(I18n.rb, className, str);
	}


	/**
	 * 添加子菜单并把事件也添加了事件
	 * name为空代表没有操作菜单，只是容器，不放在缓存map里面
	 * @param parent 父菜单
	 * @param chlid 子菜单
	 * @param name 名称
	 * @param threadLis 是否是线程执行监听器
	 */
	public void addChildMenu(final JComponent parent, final AbstractButton chlid, 
			final String name, final boolean threadLis) {
		parent.add(chlid);
		//name为空代表没有操作菜单，只是容器，不放在缓存map里面
		if(name != null) {
			chlid.setName(name);
			//反射注册事件
			chlid.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if(threadLis) {
						//线程执行,这种线程没有管理起来，可能会有重复执行的情况
						new Thread(new Runnable() {
							public void run() {
								//执行方法前，设置按钮不可操作
								chlid.setEnabled(false);
								try {
									CommonUtil.invoke(DefaultMenuBar.this, name, null);
								} catch (Exception e) {
									e.printStackTrace();
								}
								//执行方法后，设置按钮可操作
								chlid.setEnabled(true);
							}
						}).start();
					} else {
						CommonUtil.invoke(DefaultMenuBar.this, name, null);
					}
					
				}
			});
			if(menuChildMap.containsKey(name)) {
				logger.warn(name + "子菜单缓存map对象已经存在");
			}
			menuChildMap.put(name, chlid);
		}
	}
	
	/**
	 * 添加子菜单，不采用线程执行
	 * @param parent 父菜单
	 * @param chlid 子菜单
	 * @param name 名称
	 */
	protected void addChildMenu(JComponent parent, AbstractButton chlid, final String name) {
		addChildMenu(parent, chlid, name, false);
	}
	/**
	 * 外部调用工具构造器
	 * @param name 控件名称
	 * @return
	 */
	public JComponent buildButton(String name) {
		menuBuildName = name;
		this.sourceComp = build();
//		i18n();
		if(menuBarMap.containsKey(name)) {
			logger.warn(name + "主菜单缓存map对象已经存在");
		}
		menuBarMap.put(name, this);
		return this.sourceComp;
	}
	
	/**
	 * 创建复选框菜单
	 * @param name  名称
	 * @param text  显示文本
	 * @return
	 */
	protected static JCheckBoxMenuItem createCheckBoxMenuItem(String name, String text) {
		JCheckBoxMenuItem item= new JCheckBoxMenuItem(text);
		item.setName(name);
		return item;
	}
	
	/**
	 * 创建单选框菜单
	 * @param name  名称
	 * @param text  显示文本
	 * @return
	 */
	protected static JRadioButtonMenuItem createRadioButtonMenuItem(String name, String text, ButtonGroup group) {
		JRadioButtonMenuItem item= new JRadioButtonMenuItem(text);
		item.setName(name);
		group.add(item);
		return item;
	}
	
	/**
	 * 创建右键菜单项
	 * @param bean
	 * @return
	 * @throws Exception
	 */
	protected static JMenuItem createRightMenuItem(final MenuRightComponentBean bean)
			throws Exception {
		JMenuItem mi = null;
		String clazzName = bean.getMenuClass();
		if (JMenuItem.class.getName().equals(clazzName)) {
			mi = new JMenuItem();
		} else if (JRadioButtonMenuItem.class.getName().equals(clazzName)) {
			mi = new JRadioButtonMenuItem();
		} else if (JCheckBoxMenuItem.class.getName().equals(clazzName)) {
			mi = new JCheckBoxMenuItem();
		}
		if (bean.getI18nName() != null && !"".equals(bean.getI18nName())) {
			mi.setText(bean.getI18nName());
		}
		if (bean.getIcon() != null && !"".equals(bean.getIcon())) {
			mi.setIcon(new ImageIcon(bean.getIcon()));
		}
		return mi;
	}
	
	/**
	 * 获取源
	 * @return
	 */
	public JComponent getSourceComp() {
		return sourceComp;
	}
	/**
	 * 显示之前调用，不强制实现类继承
	 */
	public void beforeShow() {};
	
	/**
	 * 菜单集合
	 * @return
	 */
	public static Map<String, DefaultMenuBar> getMenuBarMap() {
		return menuBarMap;
	}
	
	/**
	 * 子菜单集合
	 * @return
	 */
	public static Map<String, AbstractButton> getMenuChildMap() {
		return menuChildMap;
	}
	/**
	 * 子菜单集合
	 * @return
	 */
	public static void setMenuChildMap(String name ,AbstractButton item) {
		if(menuChildMap.containsKey(name)) {
			logger.warn(name + "子菜单缓存map对象已经存在");
		}
		menuChildMap.put(name, item);
	}
	
	/**
	 * 非子菜单集合
	 * @return
	 */
	public static Map<String, AbstractButton> getMenuMap() {
		return menuMap;
	}
	/**
	 * 非子菜单集合
	 * @return
	 */
	public static void setMenuMap(String name ,AbstractButton item) {
		if(menuMap.containsKey(name)) {
			logger.warn(name + "菜单缓存map对象已经存在");
		}
		menuMap.put(name, item);
	}
	
}
